/*
 * Copyright (c) from 2000 to 2009
 * 
 * Network and System Laboratory 
 * Department of Computer Science 
 * College of Computer Science
 * National Chiao Tung University, Taiwan
 * All Rights Reserved.
 * 
 * This source code file is part of the NCTUns 6.0 network simulator.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation is hereby granted (excluding for commercial or
 * for-profit use), provided that both the copyright notice and this
 * permission notice appear in all copies of the software, derivative
 * works, or modified versions, and any portions thereof, and that
 * both notices appear in supporting documentation, and that credit
 * is given to National Chiao Tung University, Taiwan in all publications 
 * reporting on direct or indirect use of this code or its derivatives.
 *
 * National Chiao Tung University, Taiwan makes no representations 
 * about the suitability of this software for any purpose. It is provided 
 * "AS IS" without express or implied warranty.
 *
 * A Web site containing the latest NCTUns 6.0 network simulator software 
 * and its documentations is set up at http://NSL.csie.nctu.edu.tw/nctuns.html.
 *
 * Project Chief-Technology-Officer
 * 
 * Prof. Shie-Yuan Wang <shieyuan@csie.nctu.edu.tw>
 * National Chiao Tung University, Taiwan
 *
 * 09/01/2009
 */

#ifndef __NCTUNS_red_h__
#define __NCTUNS_red_h__

#include <object.h>
#include <packet.h>

/*
 * Define Interface Queue for every Interface
 */
struct ifqueue {
	ePacket_		*ifq_head; /* head of ifq */
	ePacket_		*ifq_tail; /* tail of ifq */
	int			ifq_len;   /* current queue length */
	int			ifq_maxlen;/* max queue length */
	int			ifq_drops; /* drops count */
};

/*
 * Early drop parameters, supplied by user
 */
struct edp {
	/*
	 * User supplied.
	 */
	double th_min;		/* minimum threshold of average queue size */
	double th_max;		/* maximum threshold of average queue size */
	double max_p;		/* maximum dropping probability */
	double q_w;			/* queue weight given to cur q size sample */
};

/*
 * Early drop variables, maintained by RED
 */
struct edv {
	double v_prob;		/* prob. of packet drop */
	int count;			/* number of packets since last drop */
	double avg_queue;   /* average queue size */
	u_int64_t q_time;   /* start of the queue idle time */
	edv() : v_prob(0.002), count(-1), avg_queue(0.0), q_time(GetCurrentTime()) { }
};

/*
 * Define Macros for IFq (interface queue)
 */
#define IF_QFULL(ifq)           ((ifq)->ifq_len >= (ifq)->ifq_maxlen)
#define IF_DROP(ifq)            ((ifq)->ifq_drops++)
#define IF_ENQUEUE(ifq, m) { \
        if ((ifq)->ifq_tail == 0) \
                (ifq)->ifq_head = m; \
        else \
                (ifq)->ifq_tail->next_ep = m; \
        (ifq)->ifq_tail = m; \
        (ifq)->ifq_len++; \
}
#define IF_PREPEND(ifq, m) { \
        (m)->next_ep = (ifq)->ifq_head; \
        if ((ifq)->ifq_tail == 0) \
                (ifq)->ifq_tail = (m); \
        (ifq)->ifq_head = (m); \
        (ifq)->ifq_len++; \
}
#define IF_DEQUEUE(ifq, m) { \
        (m) = (ifq)->ifq_head; \
        if (m) { \
                if (((ifq)->ifq_head = (m)->next_ep) == 0) \
                        (ifq)->ifq_tail = 0; \
                (m)->next_ep = 0; \
                (ifq)->ifq_len--; \
        } \
}

class RED : public NslObject {

 private:

	struct 	ifqueue if_snd; /* output interface queue */
	struct 	edp edp_; /* early drop parameters */
	struct 	edv edv_; /* early drop variables */
	double 	*bw_;

 protected:

 	int 			intrq(MBinder *);

 public :

	RED(u_int32_t type, u_int32_t id, struct plist* pl, const char *name);
	~RED();

	int			init();
	int			recv(ePacket_ *);
	int			send(ePacket_ *);
};

#endif /* __NCTUNS_red_h__ */

